package com.parleys.adapter;

import java.util.List;

import android.content.Context;
import android.graphics.Bitmap;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.TextView;

import com.parleys.R;
import com.parleys.domain.Channel;
import com.parleys.domain.ParleysListObject;
import com.parleys.domain.Presentation;
import com.parleys.domain.Space;
import com.parleys.service.intf.PresentationAssetsService;

/**
 * Handles the layout of an element in any list view in the application (except for the chapter list)
 * 
 * @author David Van Droogenbroeck
 * 
 */
public class ParleysListAdapter extends BaseAdapter {

	private static final String SPACES = "spaces";
	private static final String CHANNELS = "channels";
	private static final String PRESENTATIONS = "presentations";

	protected final List<? extends ParleysListObject> data;
	protected final Context context;
	protected final String assetBaseUrl;
	protected final PresentationAssetsService presentationAssetsService;
	protected final LayoutInflater layoutInflater;

	public ParleysListAdapter(final Context context, final List<? extends ParleysListObject> data,
			final String assetBaseUrl, final PresentationAssetsService presentationAssetsService) {
		this.context = context;
		this.data = data;
		this.assetBaseUrl = assetBaseUrl;
		this.presentationAssetsService = presentationAssetsService;
		this.layoutInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
	}

	@Override
	public int getCount() {
		return data.size();
	}

	@Override
	public Object getItem(int location) {
		return data.get(location);
	}

	@Override
	public long getItemId(int id) {
		return id;
	}

	@Override
	public View getView(final int position, final View convertedView, final ViewGroup parent) {

		View view = null;
		if (convertedView == null) {
			view = layoutInflater.inflate(R.layout.list_element, null);
			ViewWrapper viewWrapper = new ViewWrapper(view);
			view.setTag(viewWrapper);
		} else {
			view = convertedView;
		}

		final ParleysListObject parleysObject = data.get(position);
		if (parleysObject != null) {

			final ViewWrapper viewWrapper = (ViewWrapper) view.getTag();
			viewWrapper.getText1().setText(parleysObject.getName());
			viewWrapper.getText2().setText(parleysObject.getDescription());
			if (parleysObject instanceof Presentation) {
				viewWrapper.getText3().setText(((Presentation) parleysObject).getSpeakersString());
				viewWrapper.getText3().setVisibility(View.VISIBLE);
			}

			if (parleysObject.getThumbnail() != null && !"".equals(parleysObject.getThumbnail())) {

				if (presentationAssetsService.isImageCached(parleysObject.getId(), parleysObject.getThumbnail())) {
					// if we have the file locally we aren't going to bother with setting up threads.
					// We do the update in the UI thread
					final Bitmap bitmap = getImage(parleysObject);
					viewWrapper.getImageView().setImageBitmap(bitmap);
				} else {
					// set up thread mechanism to fetch images and update
					viewWrapper.getImageView().setImageResource(R.drawable.icon);

					Runnable imageFetchingRunnable = new Runnable() {
						@Override
						public void run() {
							final Bitmap bitmap = getImage(parleysObject);

							// might be null if we have closed the screen in the meanwhile
							if (parent.getHandler() != null) {
								parent.getHandler().post(new Runnable() {
									@Override
									public void run() {
										viewWrapper.getImageView().setImageBitmap(bitmap);
									}
								});
							}
						}
					};
					Thread imageFetchingThread = new Thread(imageFetchingRunnable);
					// low priority seems to give a weird effect of images updating over eachother.
					// It also means you can have a lot of active threads at a given time.
					imageFetchingThread.setPriority(Thread.NORM_PRIORITY);
					imageFetchingThread.start();
				}

			} else {
				// reset the image
				viewWrapper.getImageView().setImageBitmap(null);
			}
		}

		return view;

	}

	private Bitmap getImage(final ParleysListObject listObject) {
		Bitmap bm = null;
		if (listObject instanceof Space) {
			bm = presentationAssetsService
					.getImage(assetBaseUrl, SPACES, listObject.getId(), listObject.getThumbnail());
		} else if (listObject instanceof Channel) {
			bm = presentationAssetsService.getImage(assetBaseUrl, CHANNELS, listObject.getId(), listObject
					.getThumbnail());
		} else if (listObject instanceof Presentation) {
			bm = presentationAssetsService.getImage(assetBaseUrl, PRESENTATIONS, listObject.getId(), listObject
					.getThumbnail());
		}
		return bm;
	}

	protected class ViewWrapper {
		private View view;
		private TextView text1;
		private TextView text2;
		private TextView text3;
		private ImageView imageView;

		public ViewWrapper(View view) {
			super();
			this.view = view;
		}

		public TextView getText1() {
			if (text1 == null) {
				text1 = (TextView) view.findViewById(R.id.text1);
			}
			return text1;
		}

		public TextView getText2() {
			if (text2 == null) {
				text2 = (TextView) view.findViewById(R.id.text2);
			}
			return text2;
		}

		public TextView getText3() {
			if (text3 == null) {
				text3 = (TextView) view.findViewById(R.id.text3);
			}
			return text3;
		}

		public ImageView getImageView() {
			if (imageView == null) {
				imageView = (ImageView) view.findViewById(R.id.image);
			}
			return imageView;
		}

	}

}
